package com.example.ws_test;

import androidx.appcompat.app.AppCompatActivity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.Intent;
import android.content.res.AssetFileDescriptor;
import android.content.res.AssetManager;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;

import com.google.gson.Gson;

import org.json.JSONException;
import org.json.JSONObject;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.lang.reflect.Method;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;

public class MainActivity extends AppCompatActivity implements RosBridgeClient.RosBridgeListener {
  private static final String TAG = "MainActivity";

  private RosBridgeClient rosBridgeClient;

  private TextView messagesView;
  private EditText rosUrlEditText;
  private EditText topicEditText;
  private Spinner topicSpinner;
  private Button connectButton;
  private Button disconnectButton;
  private Button subscribeButton;
  private Button unsubscribeButton;
  private Spinner commandSpinner;
  private Button sendCommandButton;
  private Spinner coordinatesSpinner;
  private Button sendFixedCoordinatesButton;
  private Button addCoordinateButton;

  private List<String> commandTopics;
  private List<String> fixedCoordinates;
  private Map<String, String> coordinateMap;
  private static final String COORDINATES_FILE_NAME = "fixed_coordinates.txt";

  // 预定义话题列表
  private List<String> predefinedTopics;
  private Map<String, String> topicTypes;

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    // 初始化视图
    messagesView = findViewById(R.id.messages_view);
    rosUrlEditText = findViewById(R.id.ros_url_edittext);
    topicEditText = findViewById(R.id.topic_edittext);
    topicSpinner = findViewById(R.id.topics_spinner);
    connectButton = findViewById(R.id.connect_button);
    disconnectButton = findViewById(R.id.disconnect_button);
    subscribeButton = findViewById(R.id.subscribe_button);
    unsubscribeButton = findViewById(R.id.unsubscribe_button);
    commandSpinner = findViewById(R.id.command_spinner);
    sendCommandButton = findViewById(R.id.send_command_button);
    coordinatesSpinner = findViewById(R.id.coordinates_spinner);
    sendFixedCoordinatesButton = findViewById(R.id.send_fixed_coordinates_button);
    addCoordinateButton = findViewById(R.id.add_coordinate_button);

    // 初始化预定义话题
    initPredefinedTopics();

    // 初始化命令话题
    initCommandTopics();

    // 初始化固定经纬度
    initFixedCoordinates();

    // 设置适配器
    setupAdapters();

    // 设置默认ROS Bridge URL
    rosUrlEditText.setText("ws://192.168.8.134:9090");

    // 初始化ROS Bridge客户端
    rosBridgeClient = new RosBridgeClient(this);

    // 设置按钮点击监听器
    connectButton.setOnClickListener(v -> connectToRos());
    disconnectButton.setOnClickListener(v -> disconnectFromRos());
    subscribeButton.setOnClickListener(v -> subscribeToTopic());
    unsubscribeButton.setOnClickListener(v -> unsubscribeFromTopic());
    sendCommandButton.setOnClickListener(v -> sendTopic());
    sendFixedCoordinatesButton.setOnClickListener(v -> sendFixedCoordinate());
    addCoordinateButton.setOnClickListener(v -> showAddCoordinateDialog());

    updateUI(false);
  }

  // 设置适配器的方法
  private void setupAdapters() {
    // 设置预定义话题适配器
    ArrayAdapter<String> topicAdapter = new ArrayAdapter<>(this, android.R.layout.simple_spinner_item,
        predefinedTopics);
    topicAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
    topicSpinner.setAdapter(topicAdapter);

    // 设置topicSpinner监听器，选择后自动更新topicEditText
    topicSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
      @Override
      public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
        String selectedTopic = parent.getItemAtPosition(position).toString();
        topicEditText.setText(selectedTopic);
      }

      @Override
      public void onNothingSelected(AdapterView<?> parent) {
        // 不需要实现
      }
    });

    // 设置命令话题适配器
    ArrayAdapter<String> commandAdapter = new ArrayAdapter<>(this, android.R.layout.simple_spinner_item, commandTopics);
    commandAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
    commandSpinner.setAdapter(commandAdapter);

    // 创建并设置适配器
    updateCoordinatesSpinner();
    // 尝试默认选择地点7（索引为6），但要确保列表不为空且索引有效
    if (!fixedCoordinates.isEmpty() && fixedCoordinates.size() > 6) {
      coordinatesSpinner.setSelection(6);
    } else if (!fixedCoordinates.isEmpty()) {
      // 如果没有足够的项，选择第一个
      coordinatesSpinner.setSelection(0);
    }
  }

  // 不再需要useSelectedTopic方法，已替换为spinner选择监听器

  private void initPredefinedTopics() {
    // 初始化预定义话题和对应的类型
    predefinedTopics = new ArrayList<>();
    predefinedTopics.add("/service_car_stauts"); // 注意：用户提供的名称中有下划线拼写错误
    predefinedTopics.add("/rtk_raw_out");
    predefinedTopics.add("/cmd_vel_ecu");
    predefinedTopics.add("/read_status");
    predefinedTopics.add("/mobile_base/car_status");

    topicTypes = new HashMap<>();
    topicTypes.put("/service_car_stauts", "std_msgs/msg/Int32MultiArray");
    topicTypes.put("/rtk_raw_out", "std_msgs/msg/String");
    topicTypes.put("/cmd_vel_ecu", "geometry_msgs/msg/Twist");
    topicTypes.put("/read_status", "std_msgs/msg/Int8");
    topicTypes.put("/mobile_base/car_status", "std_msgs/msg/String");

    // 设置默认话题
    String currentTopic = "/read_status";
    topicEditText.setText(currentTopic);
  }

  private void initCommandTopics() {
    // 初始化命令话题
    commandTopics = new ArrayList<>();
    commandTopics.add("/target_pose_string");
    commandTopics.add("/robot_msg_value");
    commandTopics.add("/ping");
    commandTopics.add("/abc");
  }

  private void initFixedCoordinates() {
    // 初始化固定经纬度数据
    fixedCoordinates = new ArrayList<>();
    coordinateMap = new HashMap<>();

    // 从文件读取固定坐标数据
    if (!loadCoordinatesFromFile()) {
      // 如果文件不存在或读取失败，使用默认数据
      addFixedCoordinate("地点7", "116.90593610", "39.71541091");
      addFixedCoordinate("地点8", "116.90691825", "39.71549410");
      // 保存默认数据到文件
      saveCoordinatesToFile();
    }
  }

  // 从文件读取固定坐标数据
  private boolean loadCoordinatesFromFile() {
    try {
      File file = new File(getExternalFilesDir(null), COORDINATES_FILE_NAME);
      if (!file.exists()) {
        return false;
      }

      BufferedReader reader = new BufferedReader(new FileReader(file));
      String line;
      while ((line = reader.readLine()) != null) {
        String[] parts = line.split(",");
        if (parts.length >= 3) {
          String name = parts[0];
          String longitude = parts[1];
          String latitude = parts[2];
          addFixedCoordinate(name, longitude, latitude);
        }
      }
      reader.close();
      return !fixedCoordinates.isEmpty();
    } catch (IOException e) {
      e.printStackTrace();
      return false;
    }
  }

  // 保存固定坐标数据到文件
  private void saveCoordinatesToFile() {
    try {
      File file = new File(getExternalFilesDir(null), COORDINATES_FILE_NAME);
      FileWriter writer = new FileWriter(file);

      for (String name : fixedCoordinates) {
        String coords = coordinateMap.get(name);
        if (coords != null) {
          String[] parts = coords.split(",");
          if (parts.length >= 2) {
            writer.write(name + "," + parts[0] + "," + parts[1] + "\n");
          }
        }
      }

      writer.close();
    } catch (IOException e) {
      e.printStackTrace();
      Toast.makeText(this, "保存坐标数据失败", Toast.LENGTH_SHORT).show();
    }
  }

  // 显示添加新坐标的对话框
  private void showAddCoordinateDialog() {
    AlertDialog.Builder builder = new AlertDialog.Builder(this);
    builder.setTitle("添加新坐标");

    // 创建输入框
    final EditText nameInput = new EditText(this);
    nameInput.setHint("名称");
    final EditText longitudeInput = new EditText(this);
    longitudeInput.setHint("经度");
    longitudeInput.setInputType(android.text.InputType.TYPE_CLASS_NUMBER
        | android.text.InputType.TYPE_NUMBER_FLAG_DECIMAL | android.text.InputType.TYPE_NUMBER_FLAG_SIGNED);
    final EditText latitudeInput = new EditText(this);
    latitudeInput.setHint("纬度");
    latitudeInput.setInputType(android.text.InputType.TYPE_CLASS_NUMBER
        | android.text.InputType.TYPE_NUMBER_FLAG_DECIMAL | android.text.InputType.TYPE_NUMBER_FLAG_SIGNED);

    // 创建布局并添加输入框
    LinearLayout layout = new LinearLayout(this);
    layout.setOrientation(LinearLayout.VERTICAL);
    layout.setPadding(40, 20, 40, 20);
    layout.addView(nameInput);
    layout.addView(longitudeInput);
    layout.addView(latitudeInput);
    builder.setView(layout);

    // 设置按钮
    builder.setPositiveButton("确定", (dialog, which) -> {
      String name = nameInput.getText().toString().trim();
      String longitude = longitudeInput.getText().toString().trim();
      String latitude = latitudeInput.getText().toString().trim();

      if (name.isEmpty() || longitude.isEmpty() || latitude.isEmpty()) {
        Toast.makeText(MainActivity.this, "请填写所有字段", Toast.LENGTH_SHORT).show();
        return;
      }

      // 添加新坐标
      addFixedCoordinate(name, longitude, latitude);
      // 保存到文件
      saveCoordinatesToFile();
      // 更新spinner
      updateCoordinatesSpinner();
      Toast.makeText(MainActivity.this, "坐标添加成功", Toast.LENGTH_SHORT).show();
    });

    builder.setNegativeButton("取消", null);
    builder.show();
  }

  // 更新坐标spinner
  private void updateCoordinatesSpinner() {
    CoordinateAdapter coordinateAdapter = new CoordinateAdapter(this, fixedCoordinates);
    coordinatesSpinner.setAdapter(coordinateAdapter);
    // 默认选择最后一个（刚添加的）
    if (!fixedCoordinates.isEmpty()) {
      coordinatesSpinner.setSelection(fixedCoordinates.size() - 1);
    }

    // 添加选择监听器
    coordinatesSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
      @Override
      public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
        String selectedCoordinate = fixedCoordinates.get(position);
        Log.d(TAG, "选择了坐标: " + selectedCoordinate);
        // 这里可以添加选择坐标后的其他处理逻辑
      }

      @Override
      public void onNothingSelected(AdapterView<?> parent) {
        // 不需要特别处理
      }
    });
  }

  // 自定义适配器，为每个坐标项添加删除按钮
  private class CoordinateAdapter extends ArrayAdapter<String> {

    public CoordinateAdapter(Context context, List<String> coordinates) {
      // 使用系统默认的简单列表项布局
      super(context, android.R.layout.simple_spinner_item, coordinates);
      // 设置下拉视图的布局
      setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
    }

    @Override
    public View getDropDownView(int position, View convertView, ViewGroup parent) {
      return getCustomView(position, convertView, parent);
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
      // 选中状态使用系统默认视图
      if (convertView == null) {
        convertView = LayoutInflater.from(getContext()).inflate(android.R.layout.simple_spinner_item, parent, false);
      }
      TextView textView = convertView.findViewById(android.R.id.text1);
      textView.setText(getItem(position));
      return convertView;
    }

    private View getCustomView(int position, View convertView, ViewGroup parent) {
      // 重用视图或创建新视图
      if (convertView == null || !(convertView instanceof LinearLayout)) {
        convertView = LayoutInflater.from(getContext()).inflate(R.layout.coordinate_list_item, parent, false);
      }

      // 获取坐标名称
      final String coordinateName = getItem(position);
      final int currentPosition = position;

      // 设置坐标名称
      TextView nameTextView = convertView.findViewById(R.id.coordinate_name);
      nameTextView.setText(coordinateName);

      /*
       * @purpose
       * 当您在Spinner的item布局中加入Button后，Button会抢占item的焦点，导致Spinner无法正常触发OnItemSelected事件
       * <Button
       * android:id="@+id/your_button"
       * android:layout_width="wrap_content"
       * android:layout_height="wrap_content"
       * android:text="按钮"
       * android:focusable="false"
       * android:focusableInTouchMode="false"
       * android:clickable="true" />
       *
       *
       */
      // nameTextView.setOnClickListener(v -> {
      // // 手动设置spinner的选择项并关闭下拉菜单
      // coordinatesSpinner.setSelection(currentPosition, false);
      // // 强制关闭下拉菜单
      // coordinatesSpinner.post(() -> {
      // try {
      // Method method =
      // coordinatesSpinner.getClass().getDeclaredMethod("onDetachedFromWindow");
      // method.setAccessible(true);
      // method.invoke(coordinatesSpinner);
      // } catch (Exception e) {
      // // 如果反射失败，使用常规方法
      // coordinatesSpinner.setSelection(currentPosition);
      // }
      // });
      // });

      // 设置删除按钮的点击事件
      Button deleteButton = convertView.findViewById(R.id.delete_button);
      deleteButton.setOnClickListener(v -> {
        // 显示确认对话框
        new AlertDialog.Builder(MainActivity.this)
            .setTitle("确认删除")
            .setMessage("确定要删除这个坐标项吗？")
            .setPositiveButton("确定", (dialog, which) -> {
              // 删除坐标
              deleteCoordinate(coordinateName);
            })
            .setNegativeButton("取消", null)
            .show();
      });

      return convertView;
    }
  }

  // 删除坐标项
  private void deleteCoordinate(String coordinateName) {
    // 从列表和映射中删除
    fixedCoordinates.remove(coordinateName);
    coordinateMap.remove(coordinateName);

    // 更新文件
    saveCoordinatesToFile();

    // 刷新spinner
    updateCoordinatesSpinner();

    Toast.makeText(this, "坐标删除成功", Toast.LENGTH_SHORT).show();
  }

  private void addFixedCoordinate(String name, String longitude, String latitude) {
    fixedCoordinates.add(name);
    coordinateMap.put(name, longitude + "," + latitude);
  }

  private void sendTopic() {
    String selectedTopic = (String) commandSpinner.getSelectedItem();

    if (selectedTopic == null || selectedTopic.isEmpty()) {
      Toast.makeText(this, "请选择一个话题", Toast.LENGTH_SHORT).show();
      return;
    }

    JSONObject json = new JSONObject();
    try {
      // 当选择/target_pose_string时，提示用户使用固定坐标功能
      if ("/target_pose_string".equals(selectedTopic)) {
        Toast.makeText(this, "请使用固定坐标功能发送经纬度", Toast.LENGTH_SHORT).show();
        return;
      } else {
        // 对于其他话题，可以使用默认数据
        json.put("data", "default data for " + selectedTopic);
      }

      // 发送消息
      rosBridgeClient.publish(selectedTopic, "std_msgs/msg/String", json);
      // Android UI 输出
      addMessage("已发送消息到话题: " + selectedTopic + "msg:" + json.toString());

    } catch (JSONException e) {
      e.printStackTrace();
      Toast.makeText(this, "构建消息失败: " + e.getMessage(), Toast.LENGTH_SHORT).show();
    }
  }

  private void connectToRos() {
    String rosUrl = rosUrlEditText.getText().toString().trim();
    if (rosUrl.isEmpty()) {
      Toast.makeText(this, "请输入ROS Bridge URL", Toast.LENGTH_SHORT).show();
      return;
    }

    rosBridgeClient.connect(rosUrl);
    connectButton.setEnabled(false);
  }

  private void disconnectFromRos() {
    rosBridgeClient.disconnect();
  }

  private void subscribeToTopic() {
    String topic = topicEditText.getText().toString().trim();
    if (topic.isEmpty()) {
      Toast.makeText(this, "请输入话题名称", Toast.LENGTH_SHORT).show();
      return;
    }

    String topicDataType = topicTypes.get(topic);

    if (topicDataType == null || topicDataType.equals("")) {
      topicDataType = "std_msgs/msg/String";
    }

    rosBridgeClient.subscribe(topic, topicDataType);
    addMessage("已订阅话题: " + topic);
  }

  private void unsubscribeFromTopic() {
    String topic = topicEditText.getText().toString().trim();
    if (topic.isEmpty()) {
      Toast.makeText(this, "请输入话题名称", Toast.LENGTH_SHORT).show();
      return;
    }

    rosBridgeClient.unsubscribe(topic);
    addMessage("已取消订阅话题: " + topic);
  }

  private void subscribeToPredefinedTopic() {
    String topic = (String) topicSpinner.getSelectedItem();
    if (topic == null || topic.isEmpty()) {
      Toast.makeText(this, "请选择一个话题", Toast.LENGTH_SHORT).show();
      return;
    }

    String messageType = topicTypes.get(topic);
    if (messageType == null) {
      Toast.makeText(this, "未知的话题类型", Toast.LENGTH_SHORT).show();
      return;
    }

    rosBridgeClient.subscribe(topic, messageType);
    addMessage("已订阅预定义话题: " + topic + " 类型: " + messageType);
  }

  private void unsubscribeFromPredefinedTopic() {
    String topic = (String) topicSpinner.getSelectedItem();
    if (topic == null || topic.isEmpty()) {
      Toast.makeText(this, "请选择一个话题", Toast.LENGTH_SHORT).show();
      return;
    }

    rosBridgeClient.unsubscribe(topic);
    addMessage("已取消订阅预定义话题: " + topic);
  }

  private void sendFixedCoordinate() {
    String selectedLocation = (String) coordinatesSpinner.getSelectedItem();
    if (selectedLocation == null || selectedLocation.isEmpty()) {
      Toast.makeText(this, "请选择一个固定地点", Toast.LENGTH_SHORT).show();

      return;
    }

    String coordinateStr = coordinateMap.get(selectedLocation);
    if (coordinateStr == null || coordinateStr.isEmpty()) {
      Toast.makeText(this, "无法获取坐标数据", Toast.LENGTH_SHORT).show();
      return;
    }

    String[] coordinates = coordinateStr.split(",");
    if (coordinates.length != 2) {
      Toast.makeText(this, "坐标格式错误", Toast.LENGTH_SHORT).show();
      return;
    }

    String longitude = coordinates[0];
    String latitude = coordinates[1];

    // 发送固定经纬度数据到/target_pose_string话题
    sendCoordinateToTopic(longitude, latitude);

    // 选择固定坐标后播放提示声音
    playSound("xuanze-mudidi.mp3");
  }

  private void sendCoordinateToTopic(String longitude, String latitude) {
    JSONObject json = new JSONObject();
    try {
      // 构建符合要求格式的经纬度字符串
      String poseData = "lon:" + longitude + ",lat:" + latitude;
      // json.put("data", "11111");
      json.put("data", poseData);

      // 发送消息到/target_pose_string话题
      rosBridgeClient.publish("/target_pose_string", "std_msgs/msg/String", json);
      addMessage("已发送坐标到话题: /target_pose_string-msg:" + json.toString());

    } catch (JSONException e) {
      e.printStackTrace();
      Toast.makeText(this, "构建消息失败: " + e.getMessage(), Toast.LENGTH_SHORT).show();
    }
  }

  @Override
  public void onRosConnected() {
    runOnUiThread(() -> {
      Toast.makeText(MainActivity.this, "已连接到ROS", Toast.LENGTH_SHORT).show();
      updateUI(true);
      // 连接成功后播放声音
      playSound("hello.mp3");

      // 自动注册 停车提示 topic
      String topicName = "/mobile_base/car_status";
      String topicDataType = topicTypes.get(topicName);

      if (topicDataType == null || topicDataType.equals("")) {
        topicDataType = "std_msgs/msg/String";
      }

      rosBridgeClient.subscribe(topicName, topicDataType);
      addMessage("已订阅话题: " + topicName);

    });
  }

  @Override
  public void onRosDisconnected() {
    runOnUiThread(() -> {
      Toast.makeText(MainActivity.this, "已断开ROS连接", Toast.LENGTH_SHORT).show();
      updateUI(false);
      connectButton.setEnabled(true);
    });
  }

  @Override
  public void onRosError(String error) {
    runOnUiThread(() -> {
      Toast.makeText(MainActivity.this, "错误: " + error, Toast.LENGTH_LONG).show();
      connectButton.setEnabled(true);
    });
  }

  @Override
  public void onMessageReceived(String topic, JSONObject message) {
    runOnUiThread(() -> {
      try {
        // 处理不同类型的消息
        if (message.has("data")) {
          // std_msgs/String 类型
          String data = message.getString("data");
          addMessage("[" + topic + "] " + data);

          // 当接收到/mobile_base/cat_status话题且内容为boundary_pause时播放声音
          if ("/mobile_base/car_status".equals(topic) && "boundary_pause".equals(data)) {
            Toast.makeText(MainActivity.this, "开始播放声音", Toast.LENGTH_SHORT).show();
            playSound("cheliangzanting-2.mp3");
          }
        } else if (message.has("linear") && message.has("angular")) {
          // geometry_msgs/Twist 类型
          JSONObject linear = message.getJSONObject("linear");
          JSONObject angular = message.getJSONObject("angular");
          double x = linear.getDouble("x");
          double z = angular.getDouble("z");
          addMessage("[" + topic + "] 线速度: " + x + ", 角速度: " + z);
        } else {
          // 其他消息类型，直接显示JSON
          addMessage("[" + topic + "] " + message.toString());
        }
      } catch (JSONException e) {
        Log.e(TAG, "Error parsing message: " + e.getMessage());
        addMessage("[" + topic + "] " + message.toString());
      }
    });
  }

  private void addMessage(String message) {
    String timestamp = new SimpleDateFormat("HH:mm:ss", Locale.getDefault()).format(new Date());
    String currentText = messagesView.getText().toString();
    String newText = "[" + timestamp + "] " + message + "\n" + currentText;

    // 限制显示的消息数量
    if (newText.split("\n").length > 50) {
      String[] lines = newText.split("\n");
      StringBuilder limitedText = new StringBuilder();
      for (int i = 0; i < 30; i++) {
        if (i < lines.length) {
          limitedText.append(lines[i]).append("\n");
        }
      }
      newText = limitedText.toString();
    }

    messagesView.setText(newText);
  }

  private void updateUI(boolean connected) {
    connectButton.setEnabled(!connected);
    disconnectButton.setEnabled(connected);
    if (subscribeButton != null) {
      subscribeButton.setEnabled(connected);
    }
    if (unsubscribeButton != null) {
      unsubscribeButton.setEnabled(connected);
    }
    rosUrlEditText.setEnabled(!connected);
  }

  // 用于播放指定名称的音频文件
  private void playSound(String soundName) {
    MediaPlayer mediaPlayer = new MediaPlayer();
    try {
      // 设置音频流类型
      mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);

      // 获取AssetsManager
      AssetManager assetManager = getAssets();

      // 构建完整的音频文件路径
      String soundPath = "music/" + soundName;

      // 打开音频文件
      AssetFileDescriptor afd = assetManager.openFd(soundPath);

      // 设置数据源
      mediaPlayer.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength());
      afd.close();

      // 准备并播放
      mediaPlayer.prepare();
      mediaPlayer.start();

      // 设置播放完成监听器，释放MediaPlayer资源
      mediaPlayer.setOnCompletionListener(mp -> {
        mp.release();
      });

      // 设置错误监听器
      mediaPlayer.setOnErrorListener((mp, what, extra) -> {
        Log.e(TAG, "播放音频出错: " + what + ", " + extra);
        mp.release();
        return false;
      });

    } catch (Exception e) {
      Log.e(TAG, "播放音频失败: " + soundName, e);
      Toast.makeText(this, "无法播放音频: " + e.getMessage(), Toast.LENGTH_SHORT).show();
      if (mediaPlayer != null) {
        mediaPlayer.release();
      }
    }
  }

  @Override
  protected void onDestroy() {
    super.onDestroy();
    if (rosBridgeClient != null && rosBridgeClient.isConnected()) {
      rosBridgeClient.disconnect();
    }
  }
}